package com.xxh.video.controller;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.xxh.Interface.DubboSearchService;
import com.xxh.common.constant.MessageConstants;
import com.xxh.common.constant.PrefixConstants;
import com.xxh.common.myenmu.OperationType;
import com.xxh.common.utils.RedisUtil;
import com.xxh.common.utils.Result;
import com.xxh.common.utils.WebUtils;
import com.xxh.dataaccess.dto.CommentDto;
import com.xxh.dataaccess.dto.MovieDto;
import com.xxh.dataaccess.dto.upload.upLoadDto;
import com.xxh.dataaccess.entity.*;
import com.xxh.dataaccess.page.MongoPageHelper;
import com.xxh.dataaccess.page.PageResult;
import com.xxh.dataaccess.service.*;
import com.xxh.video.VideoApp;
import com.xxh.video.annotation.VideoAnnotation;
import com.xxh.video.dto.QueryParam;
import com.xxh.video.service.CategoryService;
import com.xxh.video.service.VideoService;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/video")
public class VideoController {
    @Autowired
    CategoryService categoryService;

    @Autowired
    VideoService videoService;

    @Resource
    CommentService commentService;


    @Autowired
    VideoLikeService videoLikeService;

    @Autowired
    UserCollectionService userCollectionService;

    @Autowired
    UserService userService;

    @Autowired
    MongoPageHelper mongoPageHelper;

    @Autowired
    MovieService movieService;

    @Autowired
    TagService tagService;

    @Autowired
    VideoResService videoResService;

    @Autowired
    UserMessageService userMessageService;

    @Reference
    DubboSearchService searchService;


    @Autowired
    RedisUtil redisUtil;


    //获取视频的所有类别
    @GetMapping("/listCategory")
    public Result Listcategory() {
        List<Category> categories = categoryService.listWithTree();
        Result result = Result.success();
        result.put("data", categories);
//        logger.info("用户请求过来了");
        return result;
    }


    //获取首页推广列表
    @GetMapping("/popular")
    public Result getPopularizeList() {
        Long userId = WebUtils.getUserId();
        //当前用户未登录
        if (null == userId) {

        } else {

        }
        Result result = Result.success();
        return result;
    }


    //展示所有视频
    @PostMapping("/listAll")
    public Result getAllVideos(@RequestBody QueryParam param) {

        PageResult pageResult = videoService.SelectVideosByCategory(param);
        Result result = Result.success();
        result.put("data", pageResult);
        return result;
    }

    //获取每一个大区的排行榜,参数是大区的名字
    @GetMapping("/categoryrank")
    public Result getRankList(String cname) {
        List<Video> videos = videoService.getTop20ByCategoryName(cname);
        Result result = Result.success();
        result.put("data", videos);
        return result;
    }

    //获取电影排行榜
    @GetMapping("/movieRankList")
    public Result getMovieRankList() {
        List<Movie> rankList = movieService.getRankList();
        return Result.success().put("data", rankList);
    }


    //获取视频相关性推荐列表
    @GetMapping("/getSimiaryRec")
    public Result getSimiaryRec(@RequestParam(value = "bv", required = true) String bv) {
        List<Video> videos = videoService.getSimairVideo(bv);

        return Result.success().put("videos", videos);
    }


    //电影相关性推荐
    @GetMapping("/getMovieSimaryList")
    public Result getMovieSimaryRec(@RequestParam(value = "mid", required = true) Integer mid) {
        List<Movie> movies = movieService.getSimilarMovie(mid);
        return Result.success().put("movies", movies);
    }


    //登录用户对电影的个性化推荐
    @GetMapping("/getPersonMovieRec")
    public Result getPersonMovieRec() {
        Long userId = WebUtils.getUserId();
        if (null != userId) {
            List<Movie> movies = movieService.getMovieByUid(Math.toIntExact(userId));
            if (movies.size() <= 0) {
                List<Movie> rankList = movieService.getRankList();
                return Result.success().put("movies", rankList);
            }
            return Result.success().put("movies", movies);
        } else {
            List<Movie> rankList = movieService.getRankList();
            return Result.success().put("movies", rankList);
        }
    }


    //登录用户视频的个性化推荐
    @GetMapping("/getPersonVidesRec")
    public Result getPersionVidesRec() {
        Long userId = WebUtils.getUserId();
        if (null != userId) {
            List<Video> videos = videoService.getVideoByUid(userId);
            return Result.success().put("videos", videos);
        } else {
            //未登录用户直接按热门度推荐
            List<Video> videos = videoService.getTopViewVideos();
            return Result.success().put("videos", videos);

        }
    }


    //获取当前用户对该视频状态(是否点赞，是否收藏)
    @GetMapping("/UserStatus")
    public Result videoLikeStatus(@RequestParam(value = "bv", required = true) String bv) {
        Long userId = WebUtils.getUserId();
        if (userId != null) {
            boolean b1 = videoLikeService.isLike(bv, Math.toIntExact(userId));
            boolean b2 = userCollectionService.isFavorited(bv, Math.toIntExact(userId));
            return Result.success().put("likeStatus", b1).put("favStatus", b2);
        } else {
            return Result.success().put("likeStatus", false).put("favStatus", false);
        }
    }


    //用户对电影的状态（是否收藏）
    @GetMapping("/UserMovieStatus")
    public Result MoiveFavStatus(@RequestParam(value = "mid", required = true) Integer mid) {
        Long userId = WebUtils.getUserId();
        if (userId != null) {
            boolean b = userCollectionService.isFavorited(mid, Math.toIntExact(userId));
            return Result.success().put("favStatus", b);
        } else {
            return Result.success().put("favStatus", false);
        }
    }


    //点赞操作
    @PostMapping("/likeVideo")
    @VideoAnnotation(operationType = OperationType.LIKE)
    public Result LikeVideo(@RequestParam(value = "bv", required = true) String bv) {
        //获取当前用户
        Long uid = WebUtils.getUserId();
        if (uid == null) {
            return Result.error().put("msg", "请先登录");
        } else {
            VideoLike likeLog = videoLikeService.getLikeLog(bv, Math.toIntExact(uid));
            if (null != likeLog) {
                //更新点赞状态为1
                likeLog.setStatus(1);
                videoLikeService.updateLikeStats(likeLog);
                return Result.success();
            } else {
                //视频点赞表插入一条记录
                VideoLike videoLike = new VideoLike();
                videoLike.setLikeUser(Math.toIntExact(uid));
                videoLike.setVideoId(bv);
                videoLikeService.save(videoLike);
                //点赞数+1
                videoService.AddLikeNum(bv);

                //消息表插入一条记录
                User up = videoService.getVideoUp(bv);
                UserMessage message = new UserMessage();
                message.setVideoId(bv);
                message.setType(MessageConstants.MEG_TYPE_LIKE);
                message.setFromUserId(uid);
                message.setToUserId(Long.valueOf(up.getUid()));
                message.setCreated(new Date());
                userMessageService.save(message);
                return Result.success();
            }
        }
    }


    //点赞取消
    @PostMapping("/unlikeVideo")
    public Result unlikeVideo(
            @RequestParam(value = "bv", required = true) String bv
    ) {
        //获取当前用户
        Long uid = WebUtils.getUserId();
        VideoLike likeLog = videoLikeService.getLikeLog(bv, Math.toIntExact(uid));
        if (null == likeLog) {
            VideoLike videoLike = new VideoLike();
            videoLike.setLikeUser(Math.toIntExact(uid));
            videoLike.setVideoId(bv);
            videoLike.setStatus(0);
            videoLikeService.save(videoLike);
        } else {
            likeLog.setStatus(0);
            videoLikeService.updateById(likeLog);
        }
        return Result.success();
    }

    //收藏操作
    @PostMapping("/favVideo")
    @VideoAnnotation(operationType = OperationType.FAV)
    public Result favVideo(@RequestParam(value = "bv", required = true) String bv) {
        Long userId = WebUtils.getUserId();
        if (null == userId) {
            return Result.error().put("msg", "请先登录");
        }
        if (!userCollectionService.isFavorited(bv, Math.toIntExact(userId))) {
            UserCollection collection = new UserCollection();
            collection.setBv(bv);
            collection.setUid(Math.toIntExact(userId));
            userCollectionService.save(collection);
            return Result.success().put("msg", "收藏成功");
        } else {
            return Result.error().put("msg", "无法重复收藏");
        }
    }


    @PostMapping("/favMovie")
    public Result favVideo(@RequestParam(value = "mid", required = true) Integer mid) {
        Long userId = WebUtils.getUserId();
        if (!userCollectionService.isFavorited(mid, Math.toIntExact(userId))) {
            UserCollection collection = new UserCollection();
            collection.setMid(mid);
            collection.setUid(Math.toIntExact(userId));
            userCollectionService.save(collection);
            return Result.success().put("msg", "收藏成功");
        } else {
            return Result.error().put("msg", "无法重复收藏");
        }
    }


    //所有的电影类别
    @GetMapping("/getMovieType")
    public Result getMovieType() {
        List<String> allMovieTypes = movieService.getAllMovieTypes();
        return Result.success().put("types", allMovieTypes);
    }

    //获取根据电影索引电影列表
    @GetMapping("listMovieByType")
    public Result getMoviesByTypes(@RequestParam(value = "tname") String tname,
                                   @RequestParam(value = "cur", required = false, defaultValue = "1") Integer cur,
                                   @RequestParam(value = "size", required = false, defaultValue = "20") Integer size) {
        PageResult<Movie> result = videoService.PageMovieByCategory(tname, cur, size);
        return Result.success().put("data", result);

    }


    //一般是播放界面请求这个API
    @GetMapping("/getvideoDetail")
    @VideoAnnotation(operationType = OperationType.CLICK)
    public Result getVideoDetail(String bv) {
        Long uid = WebUtils.getUserId();
        if (uid != null) {
            //构造一条history
            UserviewHistory history = new UserviewHistory();
            history.setBv(bv);
            history.setUid(Math.toIntExact(uid));
            history.setViewTime(new Date());
            //缓存用户的浏览历史，存储的格式: history_用户id : [history1, history2,…]
            redisUtil.lRightPush(PrefixConstants.Histroy + String.valueOf(uid), JSON.toJSONString(history));
        }
        Video video = videoService.getVideoByBv(bv);
        User user = userService.findByUserName(video.getName());
        Result result = Result.success().put("video", video).put("user", user);
        return result;
    }


    @GetMapping("/getmovieDetail")
    public Result getMovieDetail(Integer mid) {
        MovieDto movie = movieService.getMovieByMid(mid);
        return Result.success().put("movie", movie);
    }

    @GetMapping("/getcomments")
    public Result getComments(@RequestParam(name = "bv") String bv) {

        List<CommentDto> comments = commentService.getComments(bv);
        return Result.success().put("comments", comments);
    }

    //获取视频所有标签
    @GetMapping("/getTags")
    public Result getTags() {
        List<Tag> tags = tagService.list();
        return Result.success().put("tags", tags);
    }

    //获取视频播放地址
    @GetMapping("/getVideoResource")
    public Result getPlayResource(@RequestParam(name = "bv") String bv) {

        VideoRes res = videoResService.getById(bv);
        String url = "";
        if (null == res) {
            url = "http://123.57.11.136:9000/avbuckets/test1.mp4";
        } else {
            url = res.getUrl();
        }
        return Result.success().put("url", url);
    }

    //获取电影播放地址
    @GetMapping("/getMovieResource")
    public Result getMovieResoure(@RequestParam(name = "mid") String mid) {
        return Result.success();
    }


    //发布视频
    @PostMapping("/pbVideo")
    public Result pubVideo(@RequestBody upLoadDto upload) {

        //获取当前用户
        Long userId = WebUtils.getUserId();
        User user = userService.getById(userId);

        //构造video
        Video video = new Video();
        String bv = "bv" + IdUtil.simpleUUID();
        video.setBv(bv);
        video.setPubdate(System.currentTimeMillis());
        video.setTitle(upload.getTitle());
        video.setDesc(upload.getVideodesc());
        video.setFace(user.getHeadimgurl());
        video.setTags(upload.getTags());
        video.setTname(upload.getSubCategory());
        video.setPic(upload.getCover());
        video.setName(user.getNickname());
        //视频表插入一条记录
        videoService.SaveVideo(video);
        //资源表插入一条记录
        VideoRes videoRes = new VideoRes();
        videoRes.setBv(bv);
        videoRes.setUrl(upload.getPlayUrl());
        videoResService.save(videoRes);
        //远程调用搜索服务更新 ES 数据库
        searchService.saveVideo(video);
        return Result.success().put("msg", "上传成功");
    }


    //更新视频
    @PutMapping("/updatevideo")
    public Result updateVideo(@RequestBody Video video) {
        videoService.update(video);
        searchService.creatOrUpdateIndex(video.getBv());
        return Result.success();
    }


}
